package cc.telecomdigital.tdstock.Framework.UniqueItem;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.provider.Settings;

//*** Network SubClass ***
//Internal network receiver
public class NetworkChangeListener extends BroadcastReceiver
{
	// For external usage
	public enum CONNECT_TYPE
	{
		NONE, WIFI, MOBILE_DATA, GRPS_DATA, UNKNOWN
	}

	public interface INetworkChangeListener
	{
		/** Return on current connection type, and network info.
		    WIFI is override an GPRS and MOBILE **/
		void NetworkChange_Response(CONNECT_TYPE iConnect,
				NetworkInfo iNetInfo);
	}

	private boolean				debugMode		= false;
	private final String			LOG_TAG	= "NetworkChangeListener";

	// Remember WIFI is always override with Data Network
	private CONNECT_TYPE			connectedType;
	private NetworkInfo				networkInfo;
	private IntentFilter			networkFilterAction;

	private Context				hostContext;
	private INetworkChangeListener	interfaceReport;
	private boolean				isEnabled;

	/** Register ot use the Network status broadcast receiver **/
	public NetworkChangeListener(Context iHostContext,
			INetworkChangeListener iReportInterface)
	{
		if (debugMode)
			TDStockLog.i(LOG_TAG, "Create a New Receiver");

		isEnabled = false;
		connectedType = CONNECT_TYPE.UNKNOWN;
		hostContext = iHostContext;
		interfaceReport = iReportInterface;
		networkInfo = null;

		// Checking for 3G or GPRS data
		networkFilterAction = new IntentFilter();
		networkFilterAction.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
		networkFilterAction.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);	
	}

	/** Ask if we are using the detector **/
	public boolean IsEnabled()
	{
		return isEnabled;
	}

	/** Disable the current usage of the Broadcast receiver **/
	public synchronized void Disabled()
	{
		if (isEnabled == false)
			return;

		hostContext.unregisterReceiver(this);
		connectedType = CONNECT_TYPE.NONE;
		networkInfo = null;		
		isEnabled = false;
		if (debugMode)
			TDStockLog.i(LOG_TAG, "Unregister Receiver");
	}

	/** Enable the Broadcast Receiver
	   ** Re-Register with the system on **/
	public synchronized void Enabled()
	{
		if (isEnabled == true)
			return;

		hostContext.registerReceiver(this, networkFilterAction);
		isEnabled = true;
		if (debugMode)
			TDStockLog.i(LOG_TAG, "Register Receiver");
	}

	/** Dispose the object **/	
	public void Dispose()
	{
		Disabled();
		if (debugMode)
			TDStockLog.i(LOG_TAG, "Object has been free");
	}

	// Wifi has the higher priority than mobile
	private void AnalyzeAndSendChanges(NetworkInfo wifiInfo,
			NetworkInfo mobileInfo)
	{
		CONNECT_TYPE curType;
		if ((wifiInfo == null) && (mobileInfo == null))
		{
			curType = CONNECT_TYPE.NONE;
			if (curType == connectedType)
				return;

			connectedType = curType;
			if (interfaceReport != null)
				interfaceReport.NetworkChange_Response(connectedType, null);
			return;
		}

		curType = CONNECT_TYPE.UNKNOWN;
		networkInfo = null;
		// Wifi has higher priority
		if ((wifiInfo != null) && wifiInfo.isConnected())
		{
			curType = CONNECT_TYPE.WIFI;
			networkInfo = wifiInfo;
		}
		else if (mobileInfo != null)
		{
			if (mobileInfo.isConnected())
				curType = CONNECT_TYPE.MOBILE_DATA;
			else if ((mobileInfo.getReason() != null) && (mobileInfo.getReason().equals(DeviceInfo.gprsReason)))
				curType = CONNECT_TYPE.GRPS_DATA;
			networkInfo = mobileInfo;
		}

		if (curType == connectedType)
			return;

		connectedType = curType;
		if (interfaceReport != null)
			interfaceReport.NetworkChange_Response(connectedType,
					networkInfo);
	}

	@Override
	public void onReceive(Context context, Intent intent)
	{
		String action;
		boolean hasConnection, checkConnection;

		action = intent.getAction();
		if (debugMode)
			TDStockLog.i(LOG_TAG, "Action: " + action.toString());

		checkConnection = false;
		if (action.equals(Intent.ACTION_AIRPLANE_MODE_CHANGED)== true)
		{
			if (Settings.System.getInt(context.getContentResolver(),Settings.System.AIRPLANE_MODE_ON, 0) != 0)
			{
				if (debugMode)
					TDStockLog.i(LOG_TAG, "We are on flight mode");
				//We are on air-plane mode
				if (connectedType == CONNECT_TYPE.NONE)
					return;
				
				connectedType = CONNECT_TYPE.NONE;
				if (interfaceReport != null)
					interfaceReport.NetworkChange_Response(connectedType, null);
				return;
			}
			
			if (debugMode)
				TDStockLog.i(LOG_TAG, "We are on mobile mode again");
			checkConnection = true;
		}
		
		// We only register this action
		if (!checkConnection && action.equals(ConnectivityManager.CONNECTIVITY_ACTION) == false)
			return;

		// True returns when we have no connection
		hasConnection = intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
		
		if (debugMode)
			TDStockLog.i(LOG_TAG, "No connection: " + hasConnection);
		
		if (hasConnection)
		{
			AnalyzeAndSendChanges(null, null);
			return;
		}

		NetworkInfo wifiInfo, mobileInfo;
		ConnectivityManager connMgr;

		mobileInfo = null;
		wifiInfo   = null;
		connMgr = (ConnectivityManager)hostContext.getSystemService(Context.CONNECTIVITY_SERVICE);
		if (connMgr != null)
		{			
			//Obtain wifi Info
			wifiInfo = connMgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
			//Obtain mobile info
			mobileInfo = connMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);		
		}
		AnalyzeAndSendChanges(wifiInfo, mobileInfo);
	}

	/** Set the debug level to access information display **/
	public void SetDebugMode(boolean iEnable)
	{
		debugMode = iEnable;
	}

	/** Retrieve previous data **/
	public CONNECT_TYPE GetConnectionType()
	{
		return connectedType;
	}

	/** Get the current network information **/
	public NetworkInfo GetNetworkInfo()
	{
		if ((connectedType == CONNECT_TYPE.NONE)
				|| (connectedType == CONNECT_TYPE.UNKNOWN))
			return null;

		return networkInfo;
	}
}